﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Practices.Unity;
using MiniStock.Entities.Common;
using MiniStock.Entities.Common.Events;
using MiniStock.Infrastructure;
using System.Diagnostics;
using MiniStock.Infrastructure.Configurator;
using MiniStock.Infrastructure.Queue;

namespace MiniStock.BusinessLogic.EntityPersister
{
    public class PersisterEventQueueWorker : EventQueueWorkerBase
    {
        protected override QueuedEventWorkerBase CreateWorker(int index)
        {
            var result = RootContainer.Resolve<EntityPersisterWorker>(new ResolverOverride[]
                                                                        {
                                                                            new PropertyOverride("OutputEventQueue", this.OutputEventQueue), 
                                                                        });

            result.Name = this.Name + "." + index;
            result.InputEventQueue.Configure(RootContainer.Resolve<IEventQueueConfigurator>("InternalConfigurator"), result.Name + ".in");
            return result;
        }

        public void Configure()
        {
            var configurator = RootContainer.Resolve<IEntityPersisterConfigurator>();
            var queueConfigurator = RootContainer.Resolve<IEventQueueConfigurator>();
            var pluginConfigurator = RootContainer.Resolve<IPluginConfigurator>();
            InputEventQueue.Configure(queueConfigurator, configurator.GetInputQueueRef());
            OutputEventQueue.Configure(queueConfigurator, configurator.GetOutputQueueRef());
            this.Name = configurator.GetName();

            var plugins = pluginConfigurator.GetEntryPoints();
            foreach (var initializer in plugins.Select(i => Type.GetType(i))
                .Where(s => s != null)
                .Select(i => RootContainer.Resolve(i) as IProcessorPluginEntryPoint)
                .Where(s => s != null)
                )
            {
                SerializationHelper.RegisterKnownEventTypes(initializer.EventRootTypes);
                SerializationHelper.RegisterKnownEntityTypes(initializer.EntityRootTypes);
            }

            EntityBaseExtender.InitSerializer();
            EventBaseExtender.InitSerializer();

            InitThreadPool(configurator.GetThreadCount());
        }
    }
}
